package com.itheima.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Page;
import com.itheima.reggie.exception.BusinessException;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishFlavorMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: qingtao
 * @Date 2022/3/10 14:45
 */
@Service
public class DishServiceImpl implements DishService {
    @Autowired(required = false)
    private DishMapper dishMapper;

    @Autowired(required = false)
    private DishFlavorMapper dishFlavorMapper;

    @Autowired(required = false)
    private CategoryMapper categoryMapper;

    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    /**
     * 添加
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public boolean saveWithFlavor(DishDto dishDto) {
        Dish dish = dishMapper.findByName(dishDto.getName());
        if (dish != null){
            throw new BusinessException("添加的菜品已经存在,无法添加");
        }
        dishDto.setCreateTime(LocalDateTime.now());
        dishDto.setUpdateTime(LocalDateTime.now());
        dishDto.setStatus(1);
        dishDto.setSort(0);
        //添加菜品
        Integer save1 = dishMapper.save(dishDto);

        //口味
        List<DishFlavor> flavors =
                dishDto.getFlavors().stream().map((dishFlavor -> {
                    dishFlavor.setCreateTime(LocalDateTime.now());
                    dishFlavor.setUpdateTime(LocalDateTime.now());
                    dishFlavor.setCreateUser(dishDto.getCreateUser());
                    dishFlavor.setUpdateUser(dishDto.getUpdateUser());
                    dishFlavor.setDishId(dishDto.getId());
                    return dishFlavor;
                })).collect(Collectors.toList());
//        List<DishFlavor> flavors = dishDto.getFlavors();
//        for (DishFlavor dishFlavor : flavors) {
//            dishFlavor.setCreateTime(LocalDateTime.now());
//            dishFlavor.setUpdateTime(LocalDateTime.now());
//            dishFlavor.setCreateUser(dishDto.getCreateUser());
//            dishFlavor.setUpdateUser(dishDto.getUpdateUser());
//            dishFlavor.setDishId(dishDto.getId());
//        }
        Integer save = dishFlavorMapper.save(flavors);
        //5. 由于菜品的数据已经发生变化了，那么需要清空缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return save1 > 0 && save > 0;
    }

    /**
     * 查询1 多表
     * @param name
     * @return
     */
    @Override
    public Page<DishDto> findAllByName1(Integer page, Integer pageSize, String name) {
        PageHelper.startPage(page, pageSize);
        List<Dish> allByName = dishMapper.findAllByName1(name);
        PageInfo<Dish> pageInfo = new PageInfo<>(allByName);

        List<DishDto> dishDtoList = pageInfo.getList().stream().map((dish -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            Category category = categoryMapper.findAllById(dish.getCategoryId());
            dishDto.setCategoryName(category.getName());
            return dishDto;
        })).collect(Collectors.toList());
        return new Page<>(dishDtoList,pageInfo.getTotal(),pageInfo.getSize(),pageInfo.getPageNum());
    }

    /**
     * 查询2 连表
     * @param name
     * @return
     */
    @Override
    public Page<DishDto> findAllByName2(Integer page, Integer pageSize, String name) {
        PageHelper.startPage(page,pageSize);
        List<DishDto> dishDtoList = dishMapper.findAllByName2(name);
        PageInfo<DishDto> pageInfo = new PageInfo<>(dishDtoList);
        return new Page<>(pageInfo.getList(),pageInfo.getTotal(),pageInfo.getSize(),pageInfo.getPageNum());
    }
    /**
     * 根据ID查找
     * @param id
     * @return
     */
    @Override
    public DishDto findByID(Long id) {
        Dish dish = dishMapper.findById(id);
        List<DishFlavor> flavorList = dishFlavorMapper.findById(id);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish,dishDto);
        dishDto.setFlavors(flavorList);
        return dishDto;
    }

    /**
     * 修改
     *
     * @param dishDto
     * @param employeeId
     * @return
     */
    @Override
    @Transactional
    public boolean update(DishDto dishDto, Long employeeId) {
        Dish dishById = dishMapper.findByName(dishDto.getName());
        if (dishById!=null && !dishById.getId().equals(dishDto.getId())){
            throw new BusinessException("修改的菜品已经存在,无法修改");
        }
        //修改时间
        dishDto.setUpdateTime(LocalDateTime.now());
        //修改人
        dishDto.setUpdateUser(employeeId);
        //修改
        Integer dishUpdate = dishMapper.update(dishDto);
        //将要修改的菜品的所有口味改成is_deleted=1
//        dishFlavorMapper.updateIsDeleted(dishDto.getId());
        //删除所有该菜品的口味
        dishFlavorMapper.deleteByDishId(dishDto.getId());
        //获得DishDto的DishFlavor集合
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setCreateUser(dishDto.getCreateUser());
            flavor.setCreateTime(dishDto.getCreateTime());
//            //根据需要修改flavor对象判断是否存在
//            DishFlavor dishFlavor = dishFlavorMapper.findById1(flavor.getId());
            flavor.setUpdateTime(LocalDateTime.now());
            flavor.setUpdateUser(employeeId);
            flavor.setDishId(dishDto.getId());
//            if (dishFlavor!=null){
//                //存在调用修改
//                dishFlavorMapper.update(flavor);
//            }else {
//                //不存在调用添加方法
//                flavor.setCreateTime(LocalDateTime.now());
//                flavor.setCreateUser(employeeId);
//                flavor.setDishId(dishDto.getId());
//                dishFlavorMapper.add(flavor);
//            }
        }
        //调用添加方法
        dishFlavorMapper.save(flavors);
        //5. 由于菜品的数据已经发生变化了，那么需要清空缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return dishUpdate>0;
    }

    /**
     * 改状态（停售和启售）
     *
     * @param status
     * @param ids
     * @return
     */
    @Override
    public boolean updateStatus(Integer status, Long[] ids) {
        //5. 由于菜品的数据已经发生变化了，那么需要清空缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return dishMapper.updateStatus(status, ids)>0;
    }

    /**
     * 根据分类名查询菜品
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<DishDto> findByCategoryId(Long categoryId,Integer status) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        List<DishDto> dishDtoList =null;
        String key = "dish_"+categoryId+"_"+status;
        dishDtoList = (List<DishDto>) valueOperations.get(key);
        if (dishDtoList == null){
            List<Dish> dishList = dishMapper.findByCategoryId(categoryId,status);
            //遍历所有的dish，把dish转换为dto
            dishDtoList = dishList.stream().map(dish -> {
                DishDto dishDto = new DishDto();
                //属性拷贝
                BeanUtils.copyProperties(dish, dishDto);
                //查看该菜品的口味信息
                List<DishFlavor> dishFlavorList = dishFlavorMapper.findById(dish.getId());
                dishDto.setFlavors(dishFlavorList);
                //类别信息
                Category category = categoryMapper.findAllById(dish.getCategoryId());
                dishDto.setCategoryName(category.getName());
                return dishDto;
            }).collect(Collectors.toList());
            valueOperations.set(key,dishDtoList,60*24, TimeUnit.MINUTES);
        }
        return dishDtoList;
    }
}
